package cn.touna.jss.modules.third.baihang;

import cn.touna.jss.common.dict.entity.SysDict;
import cn.touna.jss.common.dict.service.DictService;
import cn.touna.jss.common.properties.disconf.BaiHangProperties;
import cn.touna.jss.modules.adapter.ApiMapping;
import cn.touna.jss.modules.third.baihang.entity.BaiHangRequestEntity;
import cn.touna.jss.modules.third.baihang.utils.BaiHangUtil;
import cn.touna.jss.modules.third.baihang.utils.ReportService;
import cn.touna.jss.modules.third.baihang.utils.RequestParameter;
import cn.touna.risk.api.domain.Response;
import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import com.alibaba.fastjson.JSONObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * author: xl
 * time: 2018/11/2 11:36
 * description:
 **/
@Service
public class BaiHangService {

    private static final Logger logger = LogManager.getLogger(BaiHangService.class);

    @Autowired
    BaiHangProperties baiHangProperties;

    @Autowired
    DictService dictService;


    @ApiMapping(value = "baihang.dictList",desc = "百行.征信字典数据查询")
    public Response dictList() {
        List<SysDict> list =  dictService.queryListByDataType("baihang_prdtype","");
        return new Response().success(list);
    }



    @ApiMapping(value = "baihang.queryDataInfo",desc = "百行.征信数据查询")
    public Response queryDataInfo(JSONObject baiHangRequestEntity) {
        Response response = new Response();
        logger.info("queryDataInfo req:{}", JSONObject.toJSONString(baiHangRequestEntity));
        String type = "https";
        String restURL = baiHangProperties.getRestURL()+baiHangRequestEntity.getString("productType");
        ReportService reportService = new ReportService();
        try {
            baiHangRequestEntity.put("certNo",baiHangRequestEntity.getString("idCard"));
            baiHangRequestEntity.remove("idCard");
            RequestParameter requestParameter =  getRequestParameter(baiHangRequestEntity);
            logger.info("queryDataInfo requestParameter:{}", JSONObject.toJSONString(requestParameter));
            String rawString = reportService.makePostCall(requestParameter, restURL, type);
            logger.info("queryDataInfo result:{}", rawString);
            JSONObject jsonObject = (JSONObject)JSONObject.parse(rawString);
            JSONObject headJson = jsonObject.getJSONObject("head");
            String code =  headJson.getString("responseCode");
            String responseMsg =headJson.getString("responseMsg");
            if(code.equals("0000")){
                return response.success(rawString);
            }
            return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR,responseMsg);
          } catch (Exception e) {
            e.printStackTrace();
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR,e.getMessage());
        }
    }


    @ApiMapping(value = "baihang.queryApplyCreditInfo",desc = "百行.申请信息及征信数据查询")
    public Response queryApplyCreditInfo(BaiHangRequestEntity baiHangRequestEntity) {
        Response response = new Response();
        logger.info("queryApplyCreditInfo req:{}", JSONObject.toJSONString(baiHangRequestEntity));
        ReportService reportService = new ReportService();
        try {
            String authorization= BaiHangUtil.authorization(baiHangProperties.getUsername(),baiHangProperties.getPassword());
            String result = reportService.post(baiHangProperties.getC1Url(),baiHangProperties.getType(), assembleRequsetParameter(baiHangRequestEntity),authorization);
            logger.info("queryApplyCreditInfo result:{}",result);
            JSONObject jsonObject =(JSONObject)JSONObject.parse(result);
            String errorCode = jsonObject.getString("errorCode");
            if(errorCode!=null){
                String errorMessage = jsonObject.getString("errorMessage");
                return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR,errorMessage);
            }
            return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC,jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR,e.getMessage());
        }
    }


    private JSONObject assembleRequsetParameter(BaiHangRequestEntity baiHangRequestEntity) throws Exception {
        baiHangRequestEntity.setLoanId(UUID.randomUUID().toString());
        JSONObject param = (JSONObject)JSONObject.toJSON(baiHangRequestEntity);
        param.remove("idCard");
        param.put("pid", BaiHangUtil.encrypt(baiHangProperties.getRsaPublicKey(),baiHangRequestEntity.getIdCard()));
        param.put("name", BaiHangUtil.encrypt(baiHangProperties.getRsaPublicKey(),baiHangRequestEntity.getName()));
        param.put("mobile", BaiHangUtil.encrypt(baiHangProperties.getRsaPublicKey(),baiHangRequestEntity.getMobile()));
        return param;
    }



    private RequestParameter getRequestParameter(JSONObject baiHangRequestEntity) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        RequestParameter requestParameter = new RequestParameter();
        String requestRefId = "DEMOREQ_" + new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()) + (int)((Math.random()*9+1)*100000);
        String beforeSign = "requestRefId=" + requestRefId + "&secretId=" + baiHangProperties.getSecretId();
        //生成签名
        byte[] keyBytes= new BASE64Decoder().decodeBuffer(baiHangProperties.getSecretKey());
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(beforeSign.getBytes());
        String signature = new BASE64Encoder().encode(rawHmac);

        //组装请求
        RequestParameter.Head head =  requestParameter.new Head(requestRefId,baiHangProperties.getSecretId(),signature);
        RequestParameter.Request request = requestParameter.new Request(getParaMap(baiHangRequestEntity));
        requestParameter.setSecretKey(baiHangProperties.getSecretKey());
        requestParameter.setHead(head);
        requestParameter.setRequest(request);

        return requestParameter;
    }





    private Map<String, String> getParaMap(JSONObject baiHangRequestEntity){
        List<SysDict> list =  dictService.queryListByDataType("baihang_prdtype",baiHangRequestEntity.getString("productType"));
        Map<String, String> paraMap = new HashMap<>();
        for (int i = 0; i <list.size() ; i++) {
            SysDict sysDict = list.get(i);
            String key = sysDict.getDataValue();
            paraMap.put(key,baiHangRequestEntity.getString(key));
        }
        return paraMap;
    }





}
